package com.gt.wxpay.cashier.notifyRecord.application.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gt.wxpay.cashier.common.RuleCommonUilt;
import com.gt.wxpay.cashier.domain.dto.QueryRefundDto;
import com.gt.wxpay.cashier.domain.model.NotifyTypeEnum;
import com.gt.wxpay.cashier.notifyRecord.application.NotifyRecordService;
import com.gt.wxpay.cashier.notifyRecord.domain.model.NotifyRecord;
import com.gt.wxpay.cashier.notifyRecord.infra.persistent.NotifyRecordMapper;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 通知记录*
 */
@Service
public class NotifyRecordServiceImpl extends ServiceImpl<NotifyRecordMapper, NotifyRecord> implements NotifyRecordService {

    private Logger log = LoggerFactory.getLogger(NotifyRecordServiceImpl.class);
    @Autowired
    private NotifyRecordMapper notifyRecordMapper;


    private OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .callTimeout(60, TimeUnit.SECONDS)
            .build();
    private MediaType JSON = MediaType.get("application/json; charset=utf-8");

    /**
     * 当收银台收到第三方支付系统的订单退款结果通知后，会立即调用业务系统在订单创建时提供的支付结果通知url。
     *
     * @param notifyUrl sendSuccessRefundCallBackMsg
     */
    @Override
    public boolean sendSuccessRefundCallBackMsg(String notifyUrl, QueryRefundDto queryRefundDto) {
        // 通知事件
        String jsonString = JSONObject.toJSONString(queryRefundDto);
        RequestBody body = RequestBody.create(JSON, jsonString);
        log.info("Refund通知业务侧=body==>" + jsonString);
        Request request = new Request.Builder()
                .url(notifyUrl)
                .post(body)
                .build();
        // 通知消息留痕
        NotifyRecord notifyRecord = new NotifyRecord();
        notifyRecord.setNotifyContent(jsonString);
        notifyRecord.setNotifyUrl(notifyUrl);
        notifyRecord.setNotifyType(NotifyTypeEnum.Refund_Notify.getCode());
        boolean thatWasRequestOk = false;
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String responseData = response.body().string();
                log.info(notifyUrl + "退款通知成功:" + responseData);
                thatWasRequestOk = true;
                notifyRecord.setRespCode("通知成功");
            } else {
                log.error("Refund Error: " + response.code());
                notifyRecord.setRespCode("通知异常：状态码=" + response.code());
            }
            notifyRecord.setNotifyIp(RuleCommonUilt.extractIP(notifyUrl));
        } catch (IOException e) {
            // 通知失败---收银台会每隔6分钟通知一次，总共通知10次。
            e.printStackTrace();
            notifyRecord.setRespCode("通知失败：" + e.getMessage());
        }
        this.save(notifyRecord);
        return thatWasRequestOk;
    }

    /**
     * 当收银台收到第三方支付系统的订单支付结果通知后，会立即调用业务系统在订单创建时提供的支付结果通知url。
     *
     * @param notifyUrl
     */
    @Override
    public boolean sendMqSuccessPayCallBackMsg(String notifyUrl, JSONObject bodyPay) {
        String jsonBody = bodyPay.toJSONString();
        RequestBody body = RequestBody.create(JSON, jsonBody);
        log.info("通知业务侧=body==>" + jsonBody);
        Request request = new Request.Builder()
                .url(notifyUrl)
                .post(body)
                .build();
        // 通知消息留痕
        NotifyRecord notifyRecord = new NotifyRecord();
        notifyRecord.setNotifyContent(jsonBody);
        notifyRecord.setNotifyUrl(notifyUrl);
        notifyRecord.setNotifyType(NotifyTypeEnum.Pay_Notify.getCode());

        boolean thatWasRequestOk = false;
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String responseData = response.body().string();
                log.info(notifyUrl + "通知成功:" + responseData);
                thatWasRequestOk = true;
                notifyRecord.setRespCode("通知成功");
            } else {
                log.error("Error: " + response.code());
                notifyRecord.setRespCode("通知异常：状态码=" + response.code());
            }
            notifyRecord.setNotifyIp(RuleCommonUilt.extractIP(notifyUrl));
        } catch (IOException e) {
            // 通知失败---收银台会每隔6分钟通知一次，总共通知10次。
            e.printStackTrace();
            notifyRecord.setRespCode("通知失败：" + e.getMessage());
        }
        this.save(notifyRecord);
        return thatWasRequestOk;
    }


    /**
     * @param notifyRecord
     */
    public void afterSave(NotifyRecord notifyRecord) {
    }

    /**
     * @param notifyRecord
     */
    public void afterUpdate(NotifyRecord notifyRecord) {
    }
}
